/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.bizentity.util;

import com.inspur.edp.cef.designtime.api.collection.GspAssociationCollection;
import com.inspur.edp.cef.designtime.api.element.GspElementDataType;
import com.inspur.edp.cef.designtime.api.element.GspEnumValue;
import com.inspur.edp.cef.designtime.api.variable.CommonVariable;
import com.inspur.edp.udt.designtime.api.entity.ComplexDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.SimpleDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.UnifiedDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.dbInfo.ColumnInfo;
import com.inspur.edp.udt.designtime.api.entity.dbInfo.ColumnMapType;
import com.inspur.edp.udt.designtime.api.entity.element.UdtElement;
import com.inspur.edp.udt.designtime.api.entity.enumtype.UseType;
import java.util.UUID;
import lombok.var;

;

/**
 * 更新udt字段
 */
public class UpdateBeVariableUtil {

  /**
   * 创建字段实例
   *
   * @return
   */
  private CommonVariable getChildElement() {
    CommonVariable tempVar = new CommonVariable();
    tempVar.setID(UUID.randomUUID().toString());
    return tempVar;
  }

  /**
   * 根据引用的udt元数据更新字段(模板约束均更新)
   *
   * @param element
   * @param udt
   */
  public final void updateElementWithRefUdt(CommonVariable element, UnifiedDataTypeDef udt,
      boolean isFirstChoose) {
    element.setUdtID(udt.getId());
    element.setUdtName(udt.getName());
    // 其他属性
    if (udt instanceof ComplexDataTypeDef) {
      updateComplexDataTypeDefProperties(element, (ComplexDataTypeDef) udt);
    } else if (udt instanceof SimpleDataTypeDef) {
      updateComplexDataTypeDefProperties(element, (SimpleDataTypeDef) udt, isFirstChoose);
    }
  }

  /**
   * 转换columnInfo为childElement
   *
   * @param info
   * @param prefix
   * @param ele    映射字段
   * @return
   */
  public final void mapColumnInfoToField(ColumnInfo info, String prefix, CommonVariable ele) {
    if (prefix == null || "".equals(prefix)) {
      throw new RuntimeException("请先完善当前字段的[编号]及[标签]。");
    }

    String newLabelId = prefix + "_" + info.getCode();
    ele.setLabelID(newLabelId);
    ele.setCode(newLabelId);
    ele.setName(info.getName());
    ele.setMDataType(info.getMDataType());
    ele.setDefaultValue(info.getDefaultValue());
    ele.setLength(info.getLength());
    ele.setPrecision(info.getPrecision());
  }

  //#region 单值

  /**
   * 根据单值udt更新字段的其他属性
   *
   * @param element
   * @param sUdt
   * @param isFirstChoose 是否首次选择
   */
  private void updateComplexDataTypeDefProperties(CommonVariable element, SimpleDataTypeDef sUdt,
      boolean isFirstChoose) {
    if (element.getCode() == null || "".equals(element.getCode())) {
      element.setCode(sUdt.getCode());
    }
    if (element.getName() == null || "".equals(element.getName())) {
      element.setName(sUdt.getName());
    }

    if (isFirstChoose || isConstraint(sUdt, "DataType")) {
      element.setMDataType(sUdt.getMDataType());
    }
    if (isFirstChoose || isConstraint(sUdt, "Length")) {
      element.setLength(sUdt.getLength());
    }
    if (isFirstChoose || isConstraint(sUdt, "Precision")) {
      element.setPrecision(sUdt.getPrecision());
    }
    if (isFirstChoose || isConstraint(sUdt, "ObjectType")) {
      element.setObjectType(sUdt.getObjectType());
      // 关联
      if (element.getChildAssociations() == null) {
        element.setChildAssociations(new GspAssociationCollection());
      }

      var belongElement =
          (element.getChildAssociations() != null && element.getChildAssociations().size() > 0)
              ? element.getChildAssociations().get(0).getBelongElement() : null;

      var assos = element.getChildAssociations().clone(belongElement);

      element.getChildAssociations().clear();
      if (sUdt.getChildAssociations() != null && sUdt.getChildAssociations().size() > 0) {
        throw new RuntimeException("be变量不支持选择关联udt。");
        //foreach (GspAssociation item in sUdt.ChildAssociations)
        //{
        //	var beAsso = assos?.Find(asso { return asso.Id == item.Id);
        //	element.ChildAssociations.Add(convertUdtAssociation(item, element, beAsso, isFirstChoose));
        //}
      }

      element.setEnumIndexType(sUdt.getEnumIndexType());
      // 枚举
      element.getContainEnumValues().clear();
      if (sUdt.getContainEnumValues() != null && sUdt.getContainEnumValues().size() > 0) {
        for (GspEnumValue item : sUdt.getContainEnumValues()) {
          element.getContainEnumValues().add(item);
        }
      }
    }
    if (isFirstChoose || isConstraint(sUdt, "DefaultValue")) {
      element.setDefaultValue(
          (sUdt.getDefaultValue() == null) ? null : sUdt.getDefaultValue().toString());
    }
    if (isFirstChoose || isConstraint(sUdt, "IsRequired")) {
      element.setIsRequire(sUdt.getIsRequired());
    }
    // UnifiedDataType属性，前端根据[约束]/[模板]控制属性是否可编辑
    //element.UnifiedDataType = sUdt;
  }

  /**
   * 是否约束
   *
   * @return
   */
  private boolean isConstraint(SimpleDataTypeDef sUdt, String propertyName) {
    if (sUdt.getPropertyUseTypeInfos().containsKey(propertyName)) {

      var type = sUdt.getPropertyUseTypeInfos().get(propertyName);
      return type.getPropertyUseType() == UseType.AsConstraint;
    } else {
      throw new RuntimeException("单值业务字段的约束信息中无属性名:" + propertyName);
    }
  }

  //#endregion

  //#region 多值

  /**
   * 根据多值udt更新字段的其他属性
   *
   * @param element
   * @param cUdt
   */
  private void updateComplexDataTypeDefProperties(CommonVariable element, ComplexDataTypeDef cUdt) {
    if (StringUtil.checkNull(element.getCode())) {
      element.setCode(cUdt.getCode());
    }
    if (StringUtil.checkNull(element.getName())) {
      element.setName(cUdt.getName());
    }

    UdtElement newElement;
    if (cUdt.getElements().size() == 1
        && cUdt.getDbInfo().getMappingType() != ColumnMapType.SingleColumn) {
      newElement = (UdtElement) ((cUdt.getElements().get(0) instanceof UdtElement) ? cUdt
          .getElements().get(0) : null);
    } else {
      newElement = new UdtElement(cUdt.getPropertys());
    }

    element.setObjectType(newElement.getObjectType());

    // 若为[单一列]的映射关系，可能导致超长，需把数据类型改为[Text]
    if (cUdt.getDbInfo().getMappingType() == ColumnMapType.SingleColumn) {
      element.setMDataType(GspElementDataType.Text);
      element.setLength(0);
      element.setPrecision(0);
    } else {
      element.setMDataType(newElement.getMDataType());
      element.setLength(newElement.getLength());
      element.setPrecision(newElement.getPrecision());
    }
    element.setDefaultValue(newElement.getDefaultValue());
    element.getChildAssociations().clear();
    element.getContainEnumValues().clear();
  }

  //#endregion

  //#region 关联
  //vo变量选udt时，不需要更新MappingRelation及ChildElements
  //private GspAssociation convertUdtAssociation(GspAssociation udtAsso, IGspCommonElement ele, GspAssociation beAsso,bool isFirstChoose)
  //{
  //	var asso = new GspAssociation();
  //	asso.Id = udtAsso.Id;
  //	asso.RefModel = ele.BelongObject?.BelongModel;
  //	asso.RefModelCode = udtAsso.RefModelCode;
  //	asso.RefModelID = udtAsso.RefModelID;
  //	asso.RefModelName = udtAsso.RefModelName;
  //	asso.RefModelPkgName = udtAsso.RefModelPkgName;
  //	asso.RefObjectCode = udtAsso.RefObjectCode;
  //	asso.RefObjectID = udtAsso.RefObjectID;
  //	asso.RefObjectName = udtAsso.RefObjectName;
  //	if (udtAsso.KeyCollection.Count > 0)
  //	{
  //		foreach (GspAssociationKey key in udtAsso.KeyCollection)
  //		{
  //			asso.KeyCollection.Add(convertUdtAssoKey(key, ele));
  //		}
  //	}

  //	if (isFirstChoose)
  //	{
  //		if (udtAsso.RefElementCollection.Count > 0)
  //		{
  //			foreach (CommonVariable refEle in udtAsso.RefElementCollection)
  //			{
  //				asso.RefElementCollection.Add(convertUdtRefElement(refEle as UdtElement, ele.LabelID));
  //			}
  //		}
  //	}
  //	else
  //	{
  //		var udtRefElements = udtAsso.RefElementCollection.Clone(null, udtAsso);
  //		// udt带出
  //		if (beAsso != null && beAsso.RefElementCollection != null && beAsso.RefElementCollection.Count != 0)
  //		{
  //			foreach (CommonVariable refEle in beAsso.RefElementCollection)
  //			{
  //				if (refEle.IsFromAssoUdt)
  //				{
  //					var refElement = udtRefElements.Find(item { return item.RefElementId == refEle.RefElementId);
  //					udtRefElements.Remove(refElement);
  //					// udt仍包含，则加上；udt上已删，则不加。
  //					if (refElement != null)
  //					{
  //						var refEle2 = convertUdtRefElement(refElement as UdtElement, ele.LabelID);
  //						refEle2.getID() = refEle.getID();
  //						asso.RefElementCollection.Add(refEle2);
  //					}
  //				}
  //				else
  //				{
  //					asso.RefElementCollection.Add(refEle);
  //				}
  //			}
  //		}
  //		if (udtRefElements.Count > 0)
  //		{
  //			foreach (CommonVariable refEle in udtRefElements)
  //			{
  //				asso.RefElementCollection.Add(convertUdtRefElement(refEle as UdtElement, ele.LabelID));
  //			}
  //		}
  //	}

  //	return asso;
  //}

  //private GspAssociationKey convertUdtAssoKey(GspAssociationKey udtKey, IGspCommonElement ele)
  //{
  //	var key = new GspAssociationKey();
  //	key.SourceElement = udtKey.SourceElement;
  //	key.SourceElementDisplay = udtKey.SourceElementDisplay;
  //	key.TargetElement = ele.getID();
  //	key.TargetElementDisplay = ele.Name;
  //	return key;
  //}

  //private IGspCommonElement convertUdtRefElement(UdtElement udtEle, string prefix)
  //{
  //	var bizEle = new CommonVariable();
  //	//bizEle.getID() = udtEle.getID();
  //	var newLabelId = prefix + "_" + udtEle.LabelID;
  //	bizEle.LabelID = newLabelId;
  //	bizEle.setCode( udtEle.getCode();
  //	bizEle.Name = udtEle.Name;
  //	bizEle.MDataType = udtEle.MDataType;
  //	bizEle.Length = udtEle.Length;
  //	bizEle.Precision = udtEle.Precision;
  //	bizEle.RefElementId = udtEle.RefElementId;
  //	bizEle.IsRefElement = true;
  //	bizEle.IsFromAssoUdt = true;

  //	// udt相关
  //	bizEle.IsUdt = udtEle.IsUdt;
  //	bizEle.UdtID = udtEle.UdtID;
  //	bizEle.UdtName = udtEle.UdtName;
  //	bizEle.UdtPkgName = udtEle.UdtPkgName;
  //	return bizEle;
  //}

  //#endregion
}
